package com.mr.service.impl;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;

import com.mr.dao.Dao;
import com.mr.model.BaseObject;
import com.mr.service.DaoService;

@Service("daoService")
public final class DaoServiceImpl implements DaoService{
   @Autowired@Qualifier("baseDao")
   protected Dao baseDao;
   @Autowired@Qualifier("sessionFactory")
   protected SessionFactory sessionFactory;
   public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
   }
   @Autowired@Qualifier("hibernateTemplate")
   private HibernateTemplate hibernateTemplate;
   public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
      this.hibernateTemplate = hibernateTemplate;
   }
   public void setBaseDao(Dao baseDao) {
      this.baseDao = baseDao;
   }
	
   public <T extends BaseObject> T saveObject(T entity){
   	return baseDao.saveObject(entity);
   }
   
   public <T extends BaseObject> T getObject(Class<T> clazz, Serializable id) {
      return baseDao.getObject(clazz, id);
   }
   
   public <T extends BaseObject> List<T> getAllObjects(Class<T> clazz) {
      return baseDao.getAllObjects(clazz);
   }
   
   public <T extends BaseObject> T removeObject(T entity) {
      return baseDao.removeObject(entity);
   }
	
   public <T extends BaseObject> T removeObjectById(Class<T> clazz, Serializable id) {
      T entity = baseDao.getObject(clazz, id);
      if(entity == null) return null;
      this.removeObject(entity);
      return entity;
   }
	
   public <T extends BaseObject> int getObjectCount(Class<T> clazz){
		return baseDao.getObjectCount(clazz);
   }
	
	public <T extends BaseObject> void removeObjectList(Collection<T> entityList) {
		baseDao.removeObjectList(entityList);
	}
	
	public <T extends BaseObject> void saveObjectList(Collection<T> entityList) {
		 baseDao.saveObjectList(entityList);
	}
	
	public <T extends BaseObject> void addObjectList(Collection<T> entityList) {
		baseDao.addObjectList(entityList);
	}
	
	public <T extends BaseObject, S extends Serializable> List<T> getObjectList(Class<T> clazz, Collection<S> idList) {
		return baseDao.getObjectList(clazz, idList);
	}
	
	public <T extends BaseObject> List<T> getObjectList(Class<T> clazz, String orderField, boolean asc){
		return baseDao.getObjectList(clazz, orderField, asc);
	}
	
   public <T extends BaseObject> void saveObjectList(T... entityList) {
		for(T entity: entityList){
			if(entity!= null) baseDao.saveObject(entity);
		}
   }
	@SuppressWarnings("deprecation")
	
   public boolean clearCache(String className){
      try{
         Class clazz = Class.forName(className);
         sessionFactory.evict(clazz);
         return true;
      }catch(Exception e){
     		return false;
      }
   }
	
   public <T extends BaseObject, S extends Serializable> Map<S, T> getObjectMap(Class<T> clazz, Collection<S> idList) {
		Map<S, T> result = new HashMap<S, T>();
		for(S id: idList){
			T obj = baseDao.getObject(clazz, id);
			if(obj != null) result.put(id, obj);
		}
		return result;
   }
	
   public <T extends BaseObject> Map getObjectPropertyMap(Class<T> clazz, String keyname, String valuename){
		return baseDao.getObjectPropertyMap(clazz, keyname, valuename);
	}
	
   public <T extends BaseObject> T updateObject(T entity){
		return baseDao.updateObject(entity);
	}
	
   public <T extends BaseObject> T addObject(T entity){
		return baseDao.addObject(entity);
	}
	public <T extends BaseObject> T getObjectByUkey(Class<T> clazz,
			String ukeyName, Serializable ukeyValue) {
		DetachedCriteria qry = DetachedCriteria.forClass(clazz);
		qry.add(Restrictions.eq(ukeyName, ukeyValue));
		List<T> qryList = hibernateTemplate.findByCriteria(qry);
		if(qryList.size()==0) return null;
		return qryList.get(0);
	}
}